home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / msysjour / vol06 / 05 / iconex / iconex01.c < prev    next >
Text File  |  1991-09-01  |  22KB  |  729 lines

  1. /*
  2.  * WINDOWS ICON EXTRACTION UTILITY - MAIN APPLICATION
  3.  *
  4.  * LANGUAGE : Microsoft C 6.0
  5.  * TOOLKIT  : Windows 3.0 SDK
  6.  * MODEL    : Medium
  7.  * STATUS   : Operational
  8.  *
  9.  * Copyright (C) 1991 - All Rights Reserved
  10.  *
  11.  * Eikon Systems, Inc.
  12.  * 989 East Hillsdale Blvd, Suite 260
  13.  * Foster City, California 94404
  14.  *
  15.  * 07/04/91 - Kevin P. Welch - initial creation.
  16.  *
  17.  */
  18.  
  19. #include <windows.h>
  20. #include <string.h>
  21. #include "iconex.h"
  22.  
  23. /*
  24.  * WinMain( hInst, hPrevInst, lpszCmdLine, wCmdShow ) : int
  25.  *
  26.  *    hInst          handle of current instance
  27.  *    hPrevInst      handle to previous instance (if any)
  28.  *    lpszCmdLine    pointer to command line arguments
  29.  *    wCmdShow       initial ShowWindow command
  30.  *
  31.  * This function is the system entry point for the application
  32.  * and is responsible for defining the appropriate window
  33.  * classes and for processing all the messages.  Note how
  34.  * the dialog box manager is responsible for the operation of
  35.  * the icon extraction window.
  36.  *
  37.  */
  38.  
  39. int PASCAL WinMain(
  40.    HANDLE    hInst,
  41.    HANDLE    hPrevInst,
  42.    LPSTR     lpszCmdLine,
  43.    WORD      wCmdShow )
  44. {
  45.    /* local variables */
  46.    FARPROC lpProc;
  47.  
  48.    /* display main dialog box */
  49.    lpProc = MakeProcInstance( (FARPROC)IconExDlgFn, hInst );
  50.    DialogBox( hInst, "IconEx", NULL, lpProc );
  51.    FreeProcInstance( lpProc );
  52.  
  53.    /* end program */
  54.    return( FALSE );
  55.  
  56. }
  57.  
  58. /*
  59.  * IconExDlgFn( hWnd, wMsg, wParam, lParam ) : BOOL
  60.  *
  61.  *    hWnd       handle to palette window
  62.  *    wMsg       message number
  63.  *    wParam     single word parameter
  64.  *    lParam     double word parameter
  65.  *
  66.  * This function is responsible for processing all the messages
  67.  * which relate to the icon extraction dialog box.  This mainly
  68.  * involves the definition and retrieval of the various
  69.  * events generated by the user.
  70.  *
  71.  */
  72.  
  73. BOOL FAR PASCAL IconExDlgFn(
  74.    HWND    hDlg,
  75.    WORD    wMsg,
  76.    WORD    wParam,
  77.    LONG    lParam )
  78. {
  79.    /* local variables */
  80.    BOOL  bResult;
  81.  
  82.    /* initialization */
  83.    bResult = TRUE;
  84.  
  85.    /* process messages */
  86.    switch( wMsg )
  87.       {
  88.       case WM_MEASUREITEM : /* set listbox dimensions */
  89.  
  90.          /* check for listbox id */
  91.          if ( ((LPMEASUREITEMSTRUCT)lParam)->CtlID == ID_ICONS )
  92.             ((LPMEASUREITEMSTRUCT)lParam)->itemHeight =
  93.                GetSystemMetrics(SM_CYICON) + 8;
  94.  
  95.          break;
  96.       case WM_INITDIALOG : /* initialize dialog box */
  97.          {
  98.             /* initialize property lists */
  99.             SetProp( hDlg, ICONCLIPFMT, NULL );
  100.             SetProp( hDlg, ICONDATAHANDLE, NULL );
  101.  
  102.             /* update property list */
  103.             SetProp(hDlg,
  104.                     ICONCLIPFMT,
  105.                     RegisterClipboardFormat("SDKPAINT")
  106.             );
  107.  
  108.          /* center dialog box */
  109.          CenterPopup( hDlg, NULL );
  110.  
  111.          /* define icon for dialog box - rather dirty */
  112.          SetClassWord(hDlg,
  113.                       GCW_HICON,
  114.                       LoadIcon(INSTANCE(hDlg),"Icon")
  115.          );
  116.  
  117.          /* update directory and path fields */
  118.          DlgDirList( hDlg, "*.exe", ID_FILELIST, ID_PATH, 0x4010 );
  119.  
  120.          /* set and select initial search spec */
  121.          SetDlgItemText( hDlg, ID_FILE, "*.exe" );
  122.          SendDlgItemMessage(hDlg,
  123.                             ID_FILE,
  124.                             EM_SETSEL,
  125.                             NULL,
  126.                             MAKELONG(0,0x7FFF)
  127.          );
  128.  
  129.          }
  130.          break;
  131.       case WM_COMMAND : /* window command */
  132.  
  133.       /* process sub-message */
  134.       switch( wParam )
  135.          {
  136.          case ID_FILE :
  137.             break;
  138.          case ID_FILELIST : /* directory listbox */
  139.  
  140.             /* process notification codes */
  141.             switch( HIWORD(lParam) )
  142.                {
  143.             case LBN_SELCHANGE : /* selection changed */
  144.                {
  145.                   CHAR  szDir[128];
  146.  
  147.                   /* change directories */
  148.                   if ( DlgDirSelect(hDlg,szDir,ID_FILELIST) ) {
  149.                      strcat( szDir, "*.exe" );
  150.                      SetDlgItemText( hDlg, ID_FILE, szDir );
  151.                   } else {
  152.                      SetDlgItemText( hDlg, ID_FILE, szDir );
  153.                      SendDlgItemMessage(hDlg,
  154.                                         ID_FILE,
  155.                                         EM_SETSEL,
  156.                                         NULL,
  157.                                         MAKELONG(0,0x7FFF)
  158.                      );
  159.                   }
  160.  
  161.                }
  162.                break;
  163.             case LBN_DBLCLK : /* double-click */
  164.                {
  165.                   CHAR  szDir[128];
  166.                   CHAR  szFile[128];
  167.  
  168.                   /* change directories of open file */
  169.                   if ( DlgDirSelect(hDlg,szDir,ID_FILELIST) ) {
  170.  
  171.                      /* change directories */
  172.                      strcat( szDir, "*.exe" );
  173.                      SetDlgItemText( hDlg, ID_FILE, "*.exe" );
  174.                      DlgDirList( hDlg, szDir, ID_FILELIST, ID_PATH, 0x4010 );
  175.  
  176.                   } else {
  177.  
  178.                      /* define file name */
  179.                      GetDlgItemText( hDlg, ID_PATH, szFile, sizeof(szFile) );
  180.                      if ( szFile[strlen(szFile)-1] != '\\' )
  181.                         strcat( szFile, "\\" );
  182.                      strcat( szFile, szDir );
  183.  
  184.                      /* extract icons from EXE file */
  185.                      OpenExeFile( hDlg, szFile );
  186.  
  187.                   }
  188.  
  189.                }
  190.                break;
  191.             default :
  192.                break;
  193.             }
  194.  
  195.             break;
  196.          case ID_ICONS :
  197.             {
  198.                /* process notification codes */
  199.                if ( HIWORD(lParam) == LBN_DBLCLK ) {
  200.                   /* simulate "Copy" button being clicked */
  201.                   SendMessage(hDlg,
  202.                               WM_COMMAND,
  203.                               ID_COPY,
  204.                               MAKELONG( GetDlgItem(hDlg,ID_COPY), BN_CLICKED )
  205.                   );
  206.                }
  207.             }
  208.             break;
  209.          case ID_OPEN :
  210.             {
  211.                CHAR  szDir[128];
  212.                CHAR  szFile[128];
  213.  
  214.                /* retrieve file name */
  215.                GetDlgItemText( hDlg, ID_FILE, szDir, sizeof(szDir) );
  216.  
  217.                /* change directory or open file */
  218.                if ( strchr(szDir,'*') || strchr(szDir,'?') ) {
  219.  
  220.                   /* change to new directory */
  221.                   DlgDirList( hDlg, szDir, ID_FILELIST, ID_PATH, 0x4010 );
  222.  
  223.                } else {
  224.  
  225.                   /* construct file name if path not specified */
  226.                   if ( !strchr(szDir,':') && !strchr(szDir,'\\') ) {
  227.                      GetDlgItemText( hDlg, ID_PATH, szFile, sizeof(szFile) );
  228.                      if ( szFile[strlen(szFile)-1] != '\\' )
  229.                         strcat( szFile, "\\" );
  230.                      strcat( szFile, szDir );
  231.                   } else
  232.                      strcpy( szFile, szDir );
  233.  
  234.                   /* open exe file */
  235.                   OpenExeFile( hDlg, szFile );
  236.                }
  237.             }
  238.             break;
  239.          case ID_COPY :
  240.             {
  241.                WORD       wResult;
  242.                WORD       wIndex;
  243.  
  244.                wIndex = (WORD)SendDlgItemMessage(hDlg,
  245.                                                  ID_ICONS,
  246.                                                  LB_GETCURSEL,
  247.                                                  0,
  248.                                                  0L );
  249.  
  250.                wResult = IconCopyToClipboard(hDlg,
  251.                                              GetProp( hDlg, ICONDATAHANDLE ),
  252.                                              wIndex,
  253.                                              GetProp( hDlg, ICONCLIPFMT ) );
  254.  
  255.                if (wResult)
  256.                   WARNING( hDlg, "Unable to copy icon to clipboard!" );
  257.             }
  258.             break;
  259.          case ID_EXIT : /* exit program */
  260.          EndDialog( hDlg, TRUE );
  261.          break;
  262.          case ID_ABOUT : /* about program */
  263.             Dialog( hDlg, "About", AboutDlgFn );
  264.             break;
  265.          default : /* something else */
  266.          break;
  267.       }
  268.  
  269.       break;
  270.       case WM_SYSCOMMAND : /* system command */
  271.  
  272.       /* process sub-messages */
  273.       switch( wParam )
  274.          {
  275.       case SC_CLOSE : /* destroy dialog box */
  276.          EndDialog( hDlg, TRUE );
  277.          break;
  278.       default :
  279.          bResult = FALSE;
  280.          break;
  281.       }
  282.  
  283.       break;
  284.       case WM_DRAWITEM : /* draw icon list */
  285.          {
  286.             LPDRAWITEMSTRUCT    lp;
  287.             HBRUSH              hbr;
  288.             HICON               hIcon;
  289.             RECT                rcSelect;
  290.  
  291.             /* check for listbox id */
  292.             lp = (LPDRAWITEMSTRUCT)lParam;
  293.             if ( lp->CtlID == ID_ICONS )
  294.                if ( lp->itemID == -1 ) {
  295.  
  296.                   /* define selection rectangle */
  297.                   CopyRect( &rcSelect, &lp->rcItem );
  298.                   InflateRect( &rcSelect, -3, -3 );
  299.  
  300.                   /* draw focus rectangle */
  301.                   DrawFocusRect( lp->hDC, &rcSelect );
  302.  
  303.                } else {
  304.  
  305.                   /* process action code */
  306.                   switch( lp->itemAction )
  307.                      {
  308.                   case ODA_DRAWENTIRE : /* draw entire icon */
  309.                      {
  310.                         CHAR    lpszIconDescrip[MAXLENGTH];
  311.                         WORD    wResult;
  312.  
  313.                         /* retrieve icon */
  314.                         wResult = IconCreateIcon(hDlg,
  315.                                                  GetProp(hDlg,ICONDATAHANDLE),
  316.                                                  lp->itemID,&hIcon
  317.                                   );
  318.  
  319.                         /* process return code */
  320.                         switch( wResult )
  321.                           {
  322.                         case IDERR_SUCCESS : /* successful */
  323.  
  324.                           /* draw icon */
  325.                           DrawIcon(lp->hDC,
  326.                                    lp->rcItem.left+4,
  327.                                    lp->rcItem.top+4,
  328.                                    hIcon
  329.                           );
  330.  
  331.                           /* delete icon */
  332.                           DestroyIcon( hIcon );
  333.  
  334.                           break;
  335.                         default :
  336.                           WARNING( hDlg, "Unable to draw icon!" );
  337.                           break;
  338.                         }
  339.  
  340.                         /* draw icon label */
  341.                         CopyRect( &rcSelect, &lp->rcItem );
  342.                         rcSelect.top += 4;
  343.                         rcSelect.left += GetSystemMetrics(SM_CXICON) + 8;
  344.  
  345.                         wResult=IconGetIconDescrip(GetProp(hDlg,ICONDATAHANDLE),
  346.                                                    lp->itemID,
  347.                                                    lpszIconDescrip
  348.                         );
  349.  
  350.                         if (wResult == IDERR_SUCCESS)
  351.                           DrawText(lp->hDC,
  352.                                    lpszIconDescrip,
  353.                                    -1,
  354.                                    &rcSelect,
  355.                                    DT_LEFT | DT_WORDBREAK
  356.                           );
  357.  
  358.                      }
  359.  
  360.                      /* fall through to ODA_SELECT */
  361.  
  362.                   case ODA_SELECT : /* draw selection */
  363.  
  364.                      /* define selection rectangle */
  365.                      CopyRect( &rcSelect, &lp->rcItem );
  366.                      InflateRect( &rcSelect, -1, -1 );
  367.  
  368.                      /* create brush */
  369.                      if ( lp->itemState & ODS_SELECTED ) {
  370.                         hbr =   GetStockObject( BLACK_BRUSH );
  371.                         FrameRect( lp->hDC, &rcSelect, hbr );
  372.                      } else {
  373.                         hbr = CreateSolidBrush( GetSysColor(COLOR_WINDOW) );
  374.                         FrameRect( lp->hDC, &rcSelect, hbr );
  375.                         DeleteObject( hbr );
  376.                      }
  377.  
  378.                      break;
  379.                   case ODA_FOCUS : /* draw focus */
  380.  
  381.                      /* define focus rectangle */
  382.                      CopyRect( &rcSelect, &lp->rcItem );
  383.                      InflateRect( &rcSelect, -3, -3 );
  384.  
  385.                      /* draw focus rectangle */
  386.                      DrawFocusRect( lp->hDC, &rcSelect );
  387.  
  388.                      break;
  389.                   }
  390.  
  391.                }
  392.  
  393.          }
  394.          break;
  395.       case WM_DESTROY : /* window being destroyed */
  396.          {
  397.           HANDLE   hIconData;
  398.  
  399.           /* remove property list(s) */
  400.           RemoveProp( hDlg, ICONCLIPFMT );
  401.           hIconData = RemoveProp( hDlg, ICONDATAHANDLE );
  402.           if ( hIconData )
  403.              IconFree( hIconData );
  404.          }
  405.          break;
  406.       default :
  407.       bResult = FALSE;
  408.       break;
  409.    }
  410.  
  411.    /* return result */
  412.    return( bResult );
  413.  
  414. }
  415.  
  416. /*
  417.  * AboutDlgFn( hDlg, wMsg, wParam, lParam ) : BOOL ;
  418.  *
  419.  *    hDlg       handle to dialog box
  420.  *    wMsg       message or event
  421.  *    wParam     word portion of message
  422.  *    lParam     long portion of message
  423.  *
  424.  * This function is responsible for processing all the messages
  425.  * that relate to the About dialog box.  About the only useful actions
  426.  * this function performs is to center the dialog box and to wait for
  427.  * the OK button to be pressed.
  428.  *
  429.  */
  430.  
  431. BOOL FAR PASCAL AboutDlgFn(HWND   hDlg,
  432.                            WORD   wMsg,
  433.                            WORD   wParam,
  434.                            LONG   lParam )
  435. {
  436.    BOOL        bResult;
  437.  
  438.    /* process message */
  439.    switch( wMsg )
  440.       {
  441.    case WM_INITDIALOG :
  442.       bResult = TRUE;
  443.       CenterPopup( hDlg, GetParent(hDlg) );
  444.       break;
  445.    case WM_COMMAND :
  446.  
  447.       /* process sub-message */
  448.       if ( wParam == IDOK ) {
  449.          bResult = TRUE;
  450.          EndDialog( hDlg, TRUE );
  451.       } else
  452.          bResult = FALSE;
  453.  
  454.       break;
  455.    default :
  456.       bResult = FALSE;
  457.       break;
  458.    }
  459.  
  460.    /* return final result */
  461.    return( bResult );
  462.  
  463. }
  464.  
  465. /*
  466.  * OpenExeFile( hDlg, lpszFile ) : BOOL;
  467.  *
  468.  *       hDlg       handle to dialog box
  469.  *       lpszFile   name of EXE file to open
  470.  *
  471.  * This utility function opens the named exe file, extracts the
  472.  * icons, updates the icon list and the dialog box caption.  A
  473.  * value of TRUE is returned if the function was successful, and
  474.  * FALSE otherwise.
  475.  *
  476.  */
  477.  
  478. BOOL FAR PASCAL OpenExeFile( hDlg, lpszFile )
  479.       HWND     hDlg;
  480.       LPSTR    lpszFile;
  481. {
  482.       WORD     wCount;
  483.       BOOL     bResult;
  484.       HCURSOR  hOldCursor;
  485.       CHAR     szTemp[128];
  486.  
  487.       /* initialization */
  488.       bResult = FALSE;
  489.  
  490.       /* check for valid dialog handle */
  491.       if ( IsWindow(hDlg) ) {
  492.          HANDLE      hIconDataOld;
  493.          HANDLE      hIconDataNew;
  494.  
  495.          /* initialize */
  496.          hIconDataNew = NULL;
  497.  
  498.          /* activate hourglass cursor */
  499.          hOldCursor = SetCursor( LoadCursor(NULL,IDC_WAIT) );
  500.  
  501.          /* open EXE file */
  502.          switch( IconExtract(lpszFile, &hIconDataNew ,&wCount) )
  503.             {
  504.          case IDERR_SUCCESS : /* successful */
  505.  
  506.             /* get handle to old icon data */
  507.             hIconDataOld = GetProp(hDlg,ICONDATAHANDLE);
  508.  
  509.             /* delete old icon data */
  510.             if (hIconDataOld && IconFree(hIconDataOld) != IDERR_SUCCESS)
  511.                WARNING( hDlg, "Unable to free allocated memory!" );
  512.  
  513.             /* save memory handle */
  514.             SetProp( hDlg, ICONDATAHANDLE, hIconDataNew );
  515.  
  516.             /* enable copy button */
  517.             EnableWindow( GetDlgItem(hDlg,ID_COPY), TRUE );
  518.  
  519.             /* update list of icons */
  520.          SendMessage(GetDlgItem(hDlg,ID_ICONS),
  521.                      WM_SETREDRAW,
  522.                      FALSE,
  523.                      0L
  524.             );
  525.             SendMessage(GetDlgItem(hDlg,ID_ICONS),
  526.                         LB_RESETCONTENT,
  527.                         0,
  528.                         0L
  529.             );
  530.             while ( wCount-- )
  531.                SendMessage(GetDlgItem(hDlg,ID_ICONS),
  532.                            LB_ADDSTRING,
  533.                            0,
  534.                            0L
  535.                );
  536.          SendMessage(GetDlgItem(hDlg,ID_ICONS),
  537.                      WM_SETREDRAW,
  538.                      TRUE,
  539.                      0L
  540.             );
  541.  
  542.             /* redefine caption */
  543.             wsprintf(szTemp,
  544.                      "Icon Extractor - %s",
  545.                      (LPSTR)(_fstrrchr(lpszFile,'\\')+1)
  546.             );
  547.             SetWindowText( hDlg, szTemp );
  548.  
  549.             /* select first icon */
  550.          InvalidateRect( GetDlgItem(hDlg,ID_ICONS), NULL, TRUE );
  551.             SendMessage(GetDlgItem(hDlg,ID_ICONS),
  552.                         LB_SETCURSEL,
  553.                         0,
  554.                         0L
  555.             );
  556.  
  557.             break;
  558.          case IDERR_ALLOCFAIL :
  559.             WARNING( hDlg, "Memory allocation failure!" );
  560.             break;
  561.          case IDERR_LOCKFAIL :
  562.             WARNING( hDlg, "Memory access failure!" );
  563.             break;
  564.          case IDERR_OPENFAIL :
  565.             WARNING( hDlg, "Unable to open file!" );
  566.             break;
  567.          case IDERR_READFAIL :
  568.             WARNING( hDlg, "Unable to read file!" );
  569.             break;
  570.          case IDERR_INVALIDPARAM :
  571.             WARNING( hDlg, "Invalid parameters!" );
  572.             break;
  573.          case IDERR_FILETYPEBAD :
  574.             WARNING( hDlg, "Not an executable file!" );
  575.             break;
  576.          case IDERR_EXETYPEBAD :
  577.             WARNING( hDlg, "Unsupported executable file type!" );
  578.             break;
  579.          case IDERR_WINVERSIONBAD :
  580.             WARNING( hDlg, "Unsupported Windows executable version!" );
  581.             break;
  582.          case IDERR_RESTABLEBAD :
  583.             WARNING( hDlg, "Invalid resource table in executable file!" );
  584.             break;
  585.          case IDERR_ICONBAD :
  586.             WARNING( hDlg, "Unsupported icon(s) in executable file!" );
  587.             break;
  588.          case IDERR_NOICONS :
  589.             WARNING( hDlg, "No Windows 3.0 icons found in file!" );
  590.             break;
  591.          default :
  592.             WARNING( hDlg, "Internal error!" );
  593.             break;
  594.          }
  595.  
  596.          /* restor old cursor */
  597.          SetCursor( hOldCursor );
  598.  
  599.       }
  600.  
  601.       /* return result */
  602.       return( bResult );
  603.  
  604. }
  605.  
  606. /*
  607.  * Dialog( hParentWnd, lpszTemplate, lpfnDlgProc ) : BOOL
  608.  *
  609.  *    hParentWnd        handle to parent window
  610.  *    lpszTemplate      dialog box template
  611.  *    lpfnDlgProc       dialog window function
  612.  *
  613.  * This utility function displays the specified dialog box, using the
  614.  * template provided.  It automatically makes a new instance of the
  615.  * dialog box function.  Note that this function will NOT work
  616.  * correctly if an invalid or NULL parent window handle is provided.
  617.  *
  618.  */
  619.  
  620. BOOL FAR PASCAL Dialog( hParentWnd, lpszTemplate, lpfnDlgProc )
  621.    HWND        hParentWnd;
  622.    LPSTR       lpszTemplate;
  623.    FARPROC     lpfnDlgProc;
  624. {
  625.    /* local variables */
  626.    BOOL           bResult;
  627.    FARPROC        lpProc;
  628.  
  629.    /* display palette dialog box */
  630.    lpProc = MakeProcInstance( lpfnDlgProc, INSTANCE(hParentWnd) );
  631.    bResult = DialogBox(INSTANCE(hParentWnd),
  632.                        lpszTemplate,
  633.                        hParentWnd,
  634.                        lpProc
  635.              );
  636.    FreeProcInstance( lpProc );
  637.  
  638.    /* return result */
  639.    return( bResult );
  640.  
  641. }
  642.  
  643. /*
  644.  * CenterPopup( hWnd, hParentWnd ) : BOOL
  645.  *
  646.  *    hWnd              window handle
  647.  *    hParentWnd        parent window handle
  648.  *
  649.  * This routine centers the popup window in the screen or display
  650.  * using the window handles provided.  The window is centered over
  651.  * the parent if the parent window is valid.  Special provision
  652.  * is made for the case when the popup would be centered outside
  653.  * the screen - in this case it is positioned at the appropriate
  654.  * border.
  655.  *
  656.  */
  657.  
  658. BOOL FAR PASCAL CenterPopup(
  659.       HWND     hWnd,
  660.       HWND     hParentWnd
  661.    )
  662. {
  663.    /* local variables */
  664.    int      xPopup;
  665.    int      yPopup;
  666.    int      cxPopup;
  667.    int      cyPopup;
  668.    int      cxScreen;
  669.    int      cyScreen;
  670.    int      cxParent;
  671.    int      cyParent;
  672.    RECT     rcWindow;
  673.  
  674.    /* retrieve main display dimensions */
  675.    cxScreen = GetSystemMetrics( SM_CXSCREEN );
  676.    cyScreen = GetSystemMetrics( SM_CYSCREEN );
  677.  
  678.    /* retrieve popup rectangle  */
  679.    GetWindowRect( hWnd, (LPRECT)&rcWindow );
  680.  
  681.    /* calculate popup extents */
  682.    cxPopup = rcWindow.right - rcWindow.left;
  683.    cyPopup = rcWindow.bottom - rcWindow.top;
  684.  
  685.    /* calculate bounding rectangle */
  686.    if ( hParentWnd ) {
  687.  
  688.       /* retrieve parent rectangle */
  689.       GetWindowRect( hParentWnd, (LPRECT)&rcWindow );
  690.  
  691.       /* calculate parent extents */
  692.       cxParent = rcWindow.right - rcWindow.left;
  693.       cyParent = rcWindow.bottom - rcWindow.top;
  694.  
  695.       /* center within parent window */
  696.       xPopup = rcWindow.left + ((cxParent - cxPopup)/2);
  697.       yPopup = rcWindow.top + ((cyParent - cyPopup)/2);
  698.  
  699.       /* adjust popup x-location for screen size */
  700.       if ( xPopup+cxPopup > cxScreen )
  701.          xPopup = cxScreen - cxPopup;
  702.  
  703.       /* adjust popup y-location for screen size */
  704.       if ( yPopup+cyPopup > cyScreen )
  705.          yPopup = cyScreen - cyPopup;
  706.  
  707.    } else {
  708.  
  709.       /* center within entire screen */
  710.       xPopup = (cxScreen - cxPopup) / 2;
  711.       yPopup = (cyScreen - cyPopup) / 2;
  712.  
  713.    }
  714.  
  715.    /* move window to new location & display */
  716.    MoveWindow(
  717.       hWnd,
  718.       ( xPopup > 0 ) ? xPopup : 0,
  719.       ( yPopup > 0 ) ? yPopup : 0,
  720.       cxPopup,
  721.       cyPopup,
  722.       TRUE
  723.    );
  724.  
  725.    /* normal return */
  726.    return( TRUE );
  727.  
  728. }
  729.